package com.lyf.juc.practice.aqs;

import org.junit.Test;

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.LockSupport;

/**
 * AQS  -- 抽象队列同步器
 *
 * @author LYF
 * @date 2022/6/23
 */
public class AqsTests {
    @Test
    public void test1(){
        /*
        1.层级关系
        bstract class AbstractQueuedSynchronizer
    extends AbstractOwnableSynchronizer
    implements java.io.Serializable

        2.存储结构(关键理解  CLH Node及其 CLH ）

    // Node status bits, also used as argument and return values
    static final int WAITING   = 1;          // must be 1
    static final int CANCELLED = 0x80000000; // must be negative
    static final int COND      = 2;          // in a condition wait

    // CLH Nodes
        abstract static class Node {
            volatile AbstractQueuedSynchronizer.Node prev;       // initially attached via casTail
            volatile AbstractQueuedSynchronizer.Node next;       // visibly nonnull when signallable
            Thread waiter;            // visibly nonnull when enqueued
            volatile int status;      // written by owner, atomic bit ops by others

            // methods for atomic operations
            final boolean casPrev(AbstractQueuedSynchronizer.Node c, AbstractQueuedSynchronizer.Node v) {  // for cleanQueue
                return U.weakCompareAndSetReference(this, PREV, c, v);
            }
            final boolean casNext(AbstractQueuedSynchronizer.Node c, AbstractQueuedSynchronizer.Node v) {  // for cleanQueue
                return U.weakCompareAndSetReference(this, NEXT, c, v);
            }
            final int getAndUnsetStatus(int v) {     // for signalling
                return U.getAndBitwiseAndInt(this, STATUS, ~v);
            }
            final void setPrevRelaxed(AbstractQueuedSynchronizer.Node p) {      // for off-queue assignment
                U.putReference(this, PREV, p);
            }
            final void setStatusRelaxed(int s) {     // for off-queue assignment
                U.putInt(this, STATUS, s);
            }
            final void clearStatus() {               // for reducing unneeded signals
                U.putIntOpaque(this, STATUS, 0);
            }

            private static final long STATUS
                    = U.objectFieldOffset(AbstractQueuedSynchronizer.Node.class, "status");
            private static final long NEXT
                    = U.objectFieldOffset(AbstractQueuedSynchronizer.Node.class, "next");
            private static final long PREV
                    = U.objectFieldOffset(AbstractQueuedSynchronizer.Node.class, "prev");
        }

        // Concrete classes tagged by type
        static final class ExclusiveNode extends AbstractQueuedSynchronizer.Node { }
        static final class SharedNode extends AbstractQueuedSynchronizer.Node { }

        static final class ConditionNode extends AbstractQueuedSynchronizer.Node
                implements ForkJoinPool.ManagedBlocker {
            AbstractQueuedSynchronizer.ConditionNode nextWaiter;            // link to next waiting node

             * Allows Conditions to be used in ForkJoinPools without
             * risking fixed pool exhaustion. This is usable only for
             * untimed Condition waits, not timed versions.

            public final boolean isReleasable() {
                return status <= 1 || Thread.currentThread().isInterrupted();
            }
            public final boolean block() {
                while (!isReleasable()) LockSupport.park();
                return true;
            }
        }

         #Head of the wait queue, lazily initialized.
        private transient volatile AbstractQueuedSynchronizer.Node head;

         #Tail of the wait queue. After initialization, modified only via casTail.
        private transient volatile AbstractQueuedSynchronizer.Node tail;

         #The synchronization state
        private volatile int state;

       3. 基本API及算法
       CAS算法+基本的API

         */
        AbstractQueuedSynchronizer queuedSynchronizer =new AbstractQueuedSynchronizer() {
            @Override
            protected boolean tryAcquire(int arg) {
                return super.tryAcquire(arg);
            }
        };



    }
}
